namespace MicroFrameworkDriverLibrary.Devices
{
using System;
using Microsoft.SPOT;
using MicroFrameworkDriverLibrary.Interfaces;
using Microsoft.SPOT.Hardware;

    public static class NativePort
    {
        private sealed class NativeInputPort : IInputPort
        {
            private InputPort _nativePort = null;

            public NativeInputPort(Cpu.Pin pin, bool glitchFilter, Port.ResistorMode resistorMode)
            {
                this._nativePort = new InputPort(pin, glitchFilter, resistorMode);
            }

            public bool GlitchFilter
            {
                get
                {
                    return this._nativePort.GlitchFilter;
                }
                set
                {
                    this.GlitchFilter = value;
                }
            }

            public Cpu.Pin Id
            {
                get { return this._nativePort.Id; }
            }

            public bool Read()
            {
                return this._nativePort.Read();
            }

            public Port.ResistorMode Resistor
            {
                get
                {
                    return this._nativePort.Resistor;
                }
                set
                {
                    this._nativePort.Resistor = value;
                }
            }

            public void DisableInterrupt()
            {
                this._nativePort.DisableInterrupt();
            }

            public void EnableInterrupt()
            {
                this._nativePort.EnableInterrupt();
            }
        }

        private sealed class NativeInterruptPort : IInterruptPort
        {
            private InterruptPort _nativePort = null;

            public NativeInterruptPort(Cpu.Pin pin, bool glitchFilter, Port.ResistorMode resistorMode, Port.InterruptMode interruptMode)
            {
                this._nativePort = new InterruptPort(pin, glitchFilter, resistorMode, interruptMode);
                this._nativePort.OnInterrupt += (uint data1, uint data2, DateTime time) =>
                    {
                        var localEventHandler = this.OnInterrupt;
                        if (localEventHandler != null)
                        {
                            localEventHandler(data1, data2, time);
                        }
                    };
            }

            public bool GlitchFilter
            {
                get { return this._nativePort.GlitchFilter; }
                set { this.GlitchFilter = value; }
            }

            public Cpu.Pin Id
            {
                get { return this._nativePort.Id; }
            }

            public bool Read()
            {
                return this._nativePort.Read();
            }

            public Port.ResistorMode Resistor
            {
                get { return this._nativePort.Resistor; }
                set { this._nativePort.Resistor = value; }
            }

            public Port.InterruptMode Interrupt
            {
                get { return this._nativePort.Interrupt; }
                set { this._nativePort.Interrupt = value; }
            }

            public event NativeEventHandler OnInterrupt;

            public void DisableInterrupt()
            {
                this._nativePort.DisableInterrupt();
            }

            public void EnableInterrupt()
            {
                this._nativePort.EnableInterrupt();
            }

            public void ClearInterrupt()
            {
                this._nativePort.ClearInterrupt();
            }
        }

        private sealed class NativeOutputPort : IOutputPort
        {
            private OutputPort _nativePort = null;

            public NativeOutputPort(Cpu.Pin pin, bool initialState)
            {
                this._nativePort = new OutputPort(pin, initialState);
            }

            public Cpu.Pin Id
            {
                get { return this._nativePort.Id; }
            }

            public bool InitialState
            {
                get { return this._nativePort.InitialState; }
            }

            public bool Read()
            {
                return this._nativePort.Read();
            }

            public void Write(bool value)
            {
                this._nativePort.Write(value);
            }
        }

        public static IInputPort CreateInputPort(Cpu.Pin pin, bool glitchFilter, Port.ResistorMode resistorMode)
        {
            return new NativeInputPort(pin, glitchFilter, resistorMode);
        }

        public static IInterruptPort CreateInterruptPort(Cpu.Pin pin, bool glitchFilter, Port.ResistorMode resistorMode, Port.InterruptMode interruptMode)
        {
            return new NativeInterruptPort(pin, glitchFilter, resistorMode, interruptMode);
        }

        public static IOutputPort CreateOutputPort(Cpu.Pin pin, bool initialState)
        {
            return new NativeOutputPort(pin, initialState);
        }
    }
}
